﻿using Bot.Domain.SessionChat;



using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bot.Domain.Report
{
    public enum EnumRatingLevel
    {
        Levell = 1,
        Level2 = 2,
        Level3 = 3,
        Level4 = 4,
        Level5 = 5
    }

    public class ChatbotRatingItem : BaseReportInfoItem
    {
        public int RatingTimes { get; set; }
        public int Score5Times { get; set; }
        public int Score4Times { get; set; }
        public int Score3Times { get; set; }
        public int Score2Times { get; set; }
        public int Score1Times { get; set; }
        public double AvgScore { get; set; }

        public override string GetValue(int i)
        {
            switch (i)
            {
                case 0:
                    return this.RatingTimes.ToString();
                    break;
                case 1:
                    return string.Format("{0}({1}%)", this.Score5Times, CalcAvg(this.Score5Times, this.RatingTimes, 4) * 100);
                    break;
                case 2:
                    return string.Format("{0}({1}%)", this.Score4Times, CalcAvg(this.Score4Times, this.RatingTimes, 4) * 100);
                    break;
                case 3:
                    return string.Format("{0}({1}%)", this.Score3Times, CalcAvg(this.Score3Times, this.RatingTimes, 4) * 100);
                    break;
                case 4:
                    return string.Format("{0}({1}%)", this.Score2Times, CalcAvg(this.Score2Times, this.RatingTimes, 4) * 100);
                    break;
                case 5:
                    return string.Format("{0}({1}%)", this.Score1Times, CalcAvg(this.Score1Times, this.RatingTimes, 4) * 100);
                    break;
                case 6:
                    return this.AvgScore.ToString();
                    break;
                default:
                    return "";
            }
        }
    }
    public class ChatbotRatingInfo : BaseReportInfo<ChatbotRatingItem>
    {
        public int TotalRatingTimes { get; set; }
        [JsonIgnore]
        public double TotalSumScore { get; set; }
        public int TotalScore1Times { get; set; }
        public int TotalScore2Times { get; set; }
        public int TotalScore3Times { get; set; }
        public int TotalScore4Times { get; set; }
        public int TotalScore5Times { get; set; }
        public double AvgScore { get; set; }

        [JsonIgnore]
        public override List<string> FieldList
        {
            get
            {
                return new List<string>() {
                    "Rating Times","Score 5 Times","Score 4 Times","Score 3 Times","Score 2 Times","Score 1 Times","Avg. Score"
                };
            }
        }
        public override string GetValue(int i)
        {
            switch (i)
            {
                case 0:
                    return string.Format("{0}(Total)", this.TotalRatingTimes);
                    break;
                case 1:
                    return string.Format("{0}(Total)", this.TotalScore5Times);
                    break;
                case 2:
                    return string.Format("{0}(Total)", this.TotalScore4Times);
                    break;
                case 3:
                    return string.Format("{0}(Total)", this.TotalScore3Times);
                    break;
                case 4:
                    return string.Format("{0}(Total)", this.TotalScore2Times);
                    break;
                case 5:
                    return string.Format("{0}(Total)", this.TotalScore1Times);
                    break;
                case 6:
                    return string.Format("{0}(Avg.)", this.AvgScore);
                    break;
                default:
                    return "";
            }
        }
        private double CalcAvg(double value1, double value2, int numOfDecimal = 2)
        {
            return value2 <= 0 ? 0 : Math.Round(value1 / value2, numOfDecimal);
        }
    }
    public class ChatbotRatingEntityInfo
    {
        public IList<SessionChatDto> ChatbotRatingEntityList { get; set; }
    }

    public class ChatbotRatingWrap : BasicWrap<ChatbotRatingItem, ChatbotRatingInfo, ChatbotRatingEntityInfo>
    {
        
        public static ChatbotRatingInfo GetChatbotRating(SearchCriteria search, ChatbotRatingEntityInfo entityInfo, bool ifEncode = true)
        {
            ChatbotRatingInfo result = new ChatbotRatingInfo();
            //UTCToLocal(ref entityInfo);
            switch (search.dimensionType)
            {
                case EnumDimensionType.ByTime://by time
                    result = GetInfoByTime(search, entityInfo, PushByTimeData, null, null);
                    break;
            }

            //watch.Stop();
            //System.Diagnostics.Debug.WriteLine("Calc Time: " + watch.Elapsed);

            return result;
        }

        //search the chat Source info for campaign by criteria
        private static ChatbotRatingInfo GetChatsByDimension(SearchCriteria search, ChatbotRatingEntityInfo entityInfo, bool ifEncode)
        {
            var result = new ChatbotRatingInfo();
            //result.dataType = EnumReportDataType.DataByDimension;
            //List<SessionChatDto> data = entityInfo.ChatsEntityList.Where(a=>a.CodePlanId == int.Parse(search.filterStr)).ToList();

            //result.TotalChats = data.Count;
            //if (search.dimensionType == EnumDimensionType.ByDepartment)
            //{
            //    result.TotalAgentOnly = data.Count(a=>a.ChatType== (int)EnumChatType.AgentOnly);
            //    result.TotalChatbotOnly = data.Count(a => a.ChatType == (int)EnumChatType.ChatbotOnly);
            //    result.TotalFromBotToAgent = data.Count(a => a.ChatType == (int)EnumChatType.ChatbotToAgent);
            //}

            //result.dataList = new List<ChatsItem>();

            //foreach (var item in data)
            //{
            //    var newItem = new ChatsItem();
            //    newItem.tableRowName = GetTableRowName(ifEncode, item.RequestTime);
            //    newItem.fieldId = item.FieldId;
            //    newItem.chatCount = item.Chats;
            //    newItem.chatPercentage = CalcPercent(item.Chats, result.totalChatCount);
            //    if (search.dimensionType == EnumDimensionType.ByDepartment)
            //    {
            //        newItem.fromChatButtonCount = item.ChatButtons;
            //        newItem.fromChatButtonPercentage = CalcPercent(item.ChatButtons, result.totalFromChatButtonCount);
            //        newItem.fromManuallyInvitationCount = item.ManuallyInvitations;
            //        newItem.fromManuallyInvitationPercentage = CalcPercent(item.ManuallyInvitations, result.totalFromManuallyInvitationCount);
            //        newItem.fromAutoInvitationCount = item.AutoInvitations;
            //        newItem.fromAutoInvitationPercentage = CalcPercent(item.AutoInvitations, result.totalFromAutoInvitationCount);
            //    }

            //    newItem.startTime = search.startDate.ToString();
            //    newItem.startTimeDate = search.startDate;
            //    newItem.endTime = search.endDate.ToString();
            //    newItem.endTimeDate = search.endDate;
            //    result.dataList.Add(newItem);
            //}

            //result.dataList = result.dataList.OrderByDescending(o => o.Time).ToList();
            return result;
        }

        private static ChatbotRatingInfo PushByTimeData(ChatbotRatingInfo result, ChatbotRatingEntityInfo entityInfo, SearchCriteria search)
        {
            int[] onlyBotStatus = new int[] { 0, 1, 2 };

            IEnumerable<SessionChatDto> ChatsEntityList = entityInfo.ChatbotRatingEntityList.OrderBy(c => c.RequestTime)
                .Where(a => (a.Status == 0 && a.ChatType == (int)EnumChatType.AgentOnly)
                    || (onlyBotStatus.Contains(a.Status) && a.ChatType == (int)EnumChatType.ChatbotOnly)
                    || (a.Status == 0 && a.ChatType == (int)EnumChatType.ChatbotToAgent));


            foreach (ChatbotRatingItem chatitem in result.dataList)
            {
                List<SessionChatDto> todayChatsEntityList = ChatsEntityList.Where(a => Today(chatitem, a.RequestTime, search.timeOffset)).ToList();

                chatitem.Score1Times = todayChatsEntityList.Count(a => a.RatingGrade == (int)EnumRatingLevel.Levell);
                chatitem.Score2Times = todayChatsEntityList.Count(a => a.RatingGrade == (int)EnumRatingLevel.Level2);
                chatitem.Score3Times = todayChatsEntityList.Count(a => a.RatingGrade == (int)EnumRatingLevel.Level3);
                chatitem.Score4Times = todayChatsEntityList.Count(a => a.RatingGrade == (int)EnumRatingLevel.Level4);
                chatitem.Score5Times = todayChatsEntityList.Count(a => a.RatingGrade == (int)EnumRatingLevel.Level5);
                chatitem.RatingTimes = chatitem.Score1Times+ chatitem.Score2Times+ chatitem.Score3Times+ chatitem.Score4Times+ chatitem.Score5Times;

                result.TotalRatingTimes += chatitem.RatingTimes;
                result.TotalSumScore += todayChatsEntityList.Sum(a => a.RatingGrade);

                result.TotalScore1Times += chatitem.Score1Times;
                result.TotalScore2Times += chatitem.Score2Times;
                result.TotalScore3Times += chatitem.Score3Times;
                result.TotalScore4Times += chatitem.Score4Times;
                result.TotalScore5Times += chatitem.Score5Times;

            }

            foreach (ChatbotRatingItem item in result.dataList)
            {
                item.AvgScore = CalcAvg(item.Score1Times*1+ item.Score2Times*2+ item.Score3Times*3+ item.Score4Times*4+ item.Score5Times*5, item.RatingTimes);
            }
            result.dataList = result.dataList.Reverse().ToList();
            GetListTotal(ref result, search);
            return result;
        }
        private static bool Today(ChatbotRatingItem chatsItem, DateTime utcDate,TimeSpan timeOffset)
        {
            Guid operatorId = Guid.Empty;
            operatorId = SessionHelper.GetSessionValue_CurrentOperatorId();
            DateTime localDate = DateTimeHelper.UtcToLocal(utcDate, operatorId);
            return localDate >= chatsItem.startTimeDate && localDate < chatsItem.endTimeDate;
        }
        private static void GetListTotal(ref ChatbotRatingInfo result, SearchCriteria search)
        {
            //对数据进行格式化的，取小数位2，平均值

            double divNum = 0;
            if (search.timeUnit == EnumTimeIntervalType.Distribution24_7Hour)
            {
                divNum = GetWeeksInDateRange(search.startDate, search.endDate);
            }
            else if (search.timeUnit == EnumTimeIntervalType.Distribution48HalfHour)
            {
                divNum = GetDays(search.startDate, search.endDate);
            }
            else
            {
                result.TotalRatingTimes = result.TotalRatingTimes;
                result.TotalSumScore = CalcTwoPoint(result.TotalSumScore);
                result.TotalScore1Times = result.TotalScore1Times;
                result.TotalScore2Times = result.TotalScore2Times;
                result.TotalScore3Times = result.TotalScore3Times;
                result.TotalScore4Times = result.TotalScore4Times;
                result.TotalScore5Times = result.TotalScore5Times;
                result.AvgScore = CalcAvg(result.TotalSumScore, result.TotalRatingTimes);
            }

            if (search.timeUnit == EnumTimeIntervalType.Distribution24_7Hour || search.timeUnit == EnumTimeIntervalType.Distribution48HalfHour)
            {
                result.TotalRatingTimes = result.TotalRatingTimes;
                result.TotalSumScore = CalcAvg(result.TotalSumScore, divNum);
                result.TotalScore1Times = result.TotalScore1Times;
                result.TotalScore2Times = result.TotalScore2Times;
                result.TotalScore3Times = result.TotalScore3Times;
                result.TotalScore4Times = result.TotalScore4Times;
                result.TotalScore5Times = result.TotalScore5Times;
                result.AvgScore = CalcAvg(result.TotalSumScore, result.TotalRatingTimes);
            }
        }

        #region export

        //search the New Export CSV Data for Chat Source Info by criteria
        public static NewExportCSVData GetExprotData(SearchCriteria search, ChatbotRatingEntityInfo entityInfo)
        {
            ChatbotRatingInfo info = GetChatbotRating(search, entityInfo, false);
            NewExportCSVData result = new NewExportCSVData(string.Empty, new List<NewCSVColumn>(), new DataTable());
            switch (search.dimensionType)
            {
                case EnumDimensionType.ByTime://by time
                case EnumDimensionType.ByDepartment://by department
                case EnumDimensionType.ChatbotChats://by department
                case EnumDimensionType.ChatbotAnswers://by department
                case EnumDimensionType.ChatbotHightFidenceAnswers://by department
                    {
                        result = GetExprotCSVData(search, info, info.FieldList);
                        break;
                    }
                case EnumDimensionType.RequestPage:
                    {
                        result = GetExprotCSVData(search, info, new List<string>() { info.FieldList[0] });
                        break;
                    }
            }
            return result;
        }

        #endregion

    }
}
